#ifndef _VL_SUPPORT__H_
#define _VL_SUPPORT__H_

#include <memory>

#include "env/vl_debug.h"
#include "env/vl_env.h"
#include "prop/vl_prop_inc.h"
#include "utils/vl_buffer.h"
#include "utils/vl_args.h"
#include "exception/vl_exception.h"

namespace VL {

/**
 * @Author: CimZzz
 * @Date: 2022-08-04 11:11:55
 * 
 * VL 快速构建工具多语言支持基类
 * 多语言支持
 */
class VLSupport: public std::enable_shared_from_this<VLSupport> {

public:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:13:38
	 * 
	 * 动作切面
	 */
	enum Aspect {
		/**
		 * @Author: CimZzz
		 * @Date: 2022-08-04 11:15:53
		 * 
		 * 不支持的动作
		 */
		NotSupport,

		/**
		 * @Author: CimZzz
		 * @Date: 2022-08-04 11:16:02
		 * 
		 * 生成动作类型
		 */
		Generate,

		/**
		 * @Author: CimZzz
		 * @Date: 2022-08-04 11:16:14
		 * 
		 * 编译动作类型
		 */
		Compile,

		/**
		 * @Author: CimZzz
		 * @Date: 2022-08-13 13:49:01
		 * 
		 * 依赖动作类型
		 */
		Dependency,

		/**
		 * @Author: CimZzz
		 * @Date: 2022-08-19 15:19:49
		 * 
		 * 配置动作类型
		 */
		Configure,

		/**
		 * @Author: CimZzz
		 * @Date: 2022-08-21 00:04:59
		 * 
		 * Dirty 检查动作类型
		 */
		Dirty,
	};

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-19 15:53:54
	 * 
	 * 执行动作
	 * 
	 * @param env 环境变量
	 */
	virtual void doAction(VLEnv* env);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:17:16
	 * 
	 * 获取动作切面类型
	 * 
	 * @return 动作切面类型
	 */
	Aspect getAspect() const;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:17:41
	 * 
	 * 判断当前是否为不支持的动作类型
	 * 
	 * @return 如果是返回 true
	 */
	bool isNotSupport();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:17:41
	 * 
	 * 判断当前是否为生成的动作类型
	 * 
	 * @return 如果是返回 true
	 */
	bool isGenerate();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:17:41
	 * 
	 * 判断当前是否为编译的动作类型
	 * 
	 * @return 如果是返回 true
	 */
	bool isCompile();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-13 15:53:48
	 * 
	 * 判断当前是否为依赖的动作类型
	 * 
	 * @return 如果是返回 ture
	 */
	bool isDependency();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-19 15:26:27
	 * 
	 * 判断当前是否为配置的动作类型
	 * 
	 * @return 如果是返回 true
	 */
	bool isConfigure();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 14:57:00
	 * 
	 * 抛出异常
	 * 
	 * @param fmt 异常信息格式化
	 * @param ... 不定长消息参数
	 */
	void throwException(const char * fmt, ...);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-05 17:17:43
	 * 
	 * 制造异常
	 * 
	 * @param fmt 异常信息格式化
	 * @param ... 不定长消息参数
	 */
	VLException* makeException(const char * fmt, ...);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-19 15:42:49
	 * 
	 * 初始化项目工程目录信息
	 * 
	 * @param env 环境变量
	 * 
	 * @return 如果项目存在返回 true
	 */
	bool initProject(VLEnv* env);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-19 15:42:49
	 * 
	 * 初始化项目工程目录信息, 项目必须存在, 否则抛出异常
	 * 
	 * @param env 环境变量
	 */
	void initProjectMustExist(VLEnv* env);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:21:30
	 * 
	 * 获取不支持的动作切面类型单例
	 * 
	 * @return 不支持的动作切面类型单例
	 */
	static std::shared_ptr<VLSupport> getNotSupportInstance();

protected:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:12:56
	 * 
	 * 保护构造函数, 不允许直接实例化
	 * 
	 * @param aspect 需要指定动作切面类型
	 */
	explicit VLSupport(Aspect aspect);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:33:01
	 * 
	 * 方法未实现
	 * 
	 * @param methodName 方法名
	 * 
	 * @note 抛出方法未实现的异常
	 */
	void notImplementation(const char * methodName);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 18:04:21
	 * 
	 * 加载单参数或复合参数
	 * 
	 * @param prop 属性指针
	 * @param separator 组合分隔符
	 */
	std::string loadSingleOrMultiParams(std::shared_ptr<VLProp> prop, const char * separator = " ");

private:

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:22:19
	 * 
	 * 不支持的动作类型单例
	 */
	static std::shared_ptr<VLSupport> instance;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:36:55
	 * 
	 * 获取当前动作切面名
	 * 
	 * @return 返回当前动作切面名
	 */
	const char * getTopic() const;


	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-04 11:14:30
	 * 
	 * 动作切面
	 */
	Aspect aspect;
};

};

#endif // _VL_SUPPORT__H_
